package com.ljt.yupictureddd.application.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ljt.yupictureddd.domain.space.service.SpaceUserDomainService;
import com.ljt.yupictureddd.infrastracture.mapper.SpaceUserMapper;
import com.ljt.yupictureddd.interfaces.dto.spaceuser.SpaceUserAddRequest;
import com.ljt.yupictureddd.interfaces.dto.spaceuser.SpaceUserQueryRequest;
import com.ljt.yupictureddd.domain.space.entity.Space;
import com.ljt.yupictureddd.domain.space.entity.SpaceUser;
import com.ljt.yupictureddd.domain.user.entity.User;
import com.ljt.yupictureddd.interfaces.vo.space.SpaceUserVO;
import com.ljt.yupictureddd.interfaces.vo.space.SpaceVO;
import com.ljt.yupictureddd.interfaces.vo.user.UserVO;
import com.ljt.yupictureddd.application.service.SpaceApplicationService;
import com.ljt.yupictureddd.application.service.SpaceUserApplicationService;
import com.ljt.yupictureddd.application.service.UserApplicationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @description 针对表【space_user(空间用户关联)】的数据库操作Service实现
 * @createDate 2025-01-02 20:07:15
 */
@Service
public class SpaceUserApplicationServiceImpl extends ServiceImpl<SpaceUserMapper, SpaceUser>
        implements SpaceUserApplicationService {

    @Resource
    private UserApplicationService userApplicationService;

    @Resource
    @Lazy //解决circular bug //直接在循环♻的结束的那个类，找到对应字段加入lazy
    // ┌─────┐
    // |  spaceServiceImpl
    // ↑     ↓
    // |  spaceUserServiceImpl （在这个类里面找到spaceService加上@lazy）
    // └─────┘
    private SpaceApplicationService spaceApplicationService;
    @Autowired
    private SpaceUserDomainService spaceUserDomainService;

    @Override
    public long createSpaceUser(SpaceUserAddRequest spaceUserAddRequest) {
        return spaceUserDomainService.createSpaceUser(spaceUserAddRequest);
    }

    @Override
    public void validSpaceUser(SpaceUser spaceUser, boolean add) {
        spaceUserDomainService.validSpaceUser(spaceUser, add);
    }

    @Override
    public SpaceUserVO getSpaceUserVO(SpaceUser spaceUser, HttpServletRequest request) {
        // 对象转封装类
        SpaceUserVO spaceUserVO = SpaceUserVO.objToVo(spaceUser);
        // 关联查询用户信息
        Long userId = spaceUser.getUserId();
        if (userId != null && userId > 0) {
            User user = userApplicationService.getById(userId);
            UserVO userVO = userApplicationService.getUserVO(user);
            spaceUserVO.setUser(userVO);
        }
        // 关联查询空间信息
        Long spaceId = spaceUser.getSpaceId();
        if (spaceId != null && spaceId > 0) {
            Space space = spaceApplicationService.getById(spaceId);
            SpaceVO spaceVO = spaceApplicationService.getSpaceVO(space, request);
            spaceUserVO.setSpace(spaceVO);
        }
        return spaceUserVO;
    }

    @Override
    public List<SpaceUserVO> getSpaceUserVOList(List<SpaceUser> spaceUserList) {
        // 判断输入列表是否为空
        if (CollUtil.isEmpty(spaceUserList)) {
            return Collections.emptyList();
        }
        // 对象列表 => 封装对象列表
        List<SpaceUserVO> spaceUserVOList = spaceUserList.stream().map(SpaceUserVO::objToVo).collect(Collectors.toList());
        // 1. 收集需要关联查询的用户 ID 和空间 ID
        Set<Long> userIdSet = spaceUserList.stream().map(SpaceUser::getUserId).collect(Collectors.toSet());
        Set<Long> spaceIdSet = spaceUserList.stream().map(SpaceUser::getSpaceId).collect(Collectors.toSet());
        // 2. 批量查询用户和空间
        Map<Long, List<User>> userIdUserListMap = userApplicationService.listByIds(userIdSet).stream()
                .collect(Collectors.groupingBy(User::getId));
        Map<Long, List<Space>> spaceIdSpaceListMap = spaceApplicationService.listByIds(spaceIdSet).stream()
                .collect(Collectors.groupingBy(Space::getId));
        // 3. 填充 SpaceUserVO 的用户和空间信息
        spaceUserVOList.forEach(spaceUserVO -> {
            Long userId = spaceUserVO.getUserId();
            Long spaceId = spaceUserVO.getSpaceId();
            // 填充用户信息
            User user = null;
            if (userIdUserListMap.containsKey(userId)) {
                user = userIdUserListMap.get(userId).get(0);
            }
            spaceUserVO.setUser(userApplicationService.getUserVO(user));
            // 填充空间信息
            Space space = null;
            if (spaceIdSpaceListMap.containsKey(spaceId)) {
                space = spaceIdSpaceListMap.get(spaceId).get(0);
            }
            spaceUserVO.setSpace(SpaceVO.objToVo(space));
        });
        return spaceUserVOList;
    }

    @Override
    public QueryWrapper<SpaceUser> getQueryWrapper(SpaceUserQueryRequest spaceUserQueryRequest) {
        return spaceUserDomainService.getQueryWrapper(spaceUserQueryRequest);
    }
}

